<!DOCTYPE html>
<html>
<head>
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
    <meta charset="UTF-8">
    <title>ArozOS IoT Hub</title>
    <link rel="stylesheet" href="../../../script/semantic/semantic.min.css">
    <link rel="manifest" href="manifest.json">
	<script src="../../../script/jquery.min.js"></script>
    <script src="../../../script/semantic/semantic.min.js"></script>
    <script src="../../../script/ao_module.js"></script>
    <style>
        .ultrasmall.image{
            height:35px;
            margin:0px !important;
            margin-right:10px !important;
        }
        .selectable{
            cursor:pointer;
        }
        .selectable:hover{
            background-color:#f0f0f0;
            
        }
        .noborder{
            border: 1px solid transparent !important;
        }
        .controlBtn{
            position:absolute;
            right:8px;
            bottom:8px;
        }
        .devIcon{
            border-radius: 10px;
        }
        .primary.button{
            background-color: #4aa9eb !important;
        }
        .bottom.item{
            position:absolute;
            bottom: 0px;
            left:0px;
            width:100%;
            font-size:80%;
        }
        #sideMenu{
            height: calc(100% - 85px);
        }
		.primary.button{
			background-color: #4287f5 !important;
		}
        body{
            height:100%;
            background:rgba(247,247,247,0.95);
        }

		.popupInterface{
			height:80%;
			width:95%;
			overflow-y:auto;
		}
    </style>
</head>


<body>
	<div id="sidemenu" class="ui right vertical menu sidebar">
	   <div class="item">
		  <div class="ui header">
			 ArozOS IoT Hub
			 <div class="sub header">Universal IoT Controller</div>
		  </div>
	   </div>
	   <a class="selectable item" onClick="loadDevList();hideSideMenu();">
	   <i class="refresh icon"></i> Refresh List
	   </a>
	   <a class="selectable item" onClick="scanDevices();hideSideMenu();">
	   <i class="search icon"></i> Scan Devices
	   </a>
	   <div class="bottom item">
		  CopyRight ArozOS Project 2020 - <span class="thisYear"></span>
	   </div>
	</div>
	<div class="pusher">
	   <div class="ui menu">
		  <a class="item noborder" href="index.html"><img class="ui ultrasmall circular image" src="img/menu_icon.svg"> IoT Hub</a>
		  <a class="right item" onClick="toggleSideMenu();"><i class="content icon"></i></a>
	   </div>
	   <div id="devList" class="ui container">
			<div class="ui basic segment HDSDev">
				<div class="ui grid">
					<div class="four wide column"><img class="ui tiny devIcon image" src="img/system/loading.gif"></div>
					<div class="twelve wide column">
						<div class="ui container">
							<div class="ui header">
								<span class="devHeader">Scanning</span>
								<div class="sub devProperty header">IoT Hub take a while to scan your network for the first startup.</div>
							</div>
						</div>
					</div>
				</div>
			</div>
	   </div>
	   <br><br><br>
	</div>

	<!-- Show more information about thsi device-->
	<div id="moreInfoInterface" class="ui active dimmer" style="display:none;">
	   <div style="position:absolute;width:100%;height:100%;left:0px;top:0px;" onClick='$("#moreInfoInterface").fadeOut("fast");'>
	   </div>
	   <div id="informationItnerface" class="ui segment mainUI popupInterface" style="text-align: left;">
		  <div class="ui header">
			 Device Properties
		  </div>
		  <br>
		  <div class="ui horizontal form">
			 <div class="field">
				<label>Device UUID</label>
				<input id="duid" type="text" readonly="true">
			 </div>
			 <div class="field">
				<label>IP Address</label>
				<input id="ipaddr" type="text"  readonly="true">
			 </div>
			 <div class="field">
				<label>Communication Port</label>
				<input id="comport" type="text"  readonly="true">
			 </div>
			 <div class="field">
				<label>Manufacturer</label>
				<input id="manufacturer" type="text"  readonly="true">
			 </div>
			 <div class="field">
				<label>Version</label>
				<input id="version" type="text"  readonly="true">
			 </div>
		  </div>
		  <br>
		  <button class="ui primary button"  onClick='$("#moreInfoInterface").fadeOut("fast");'>Close</button>
		  <br><br>
	   </div>
	</div>

	<!-- Editing can be done on this device -->
	<div id="editInterface" class="ui active dimmer" style="display:none;">
		<div style="position:absolute;width:100%;height:100%;left:0px;top:0px;" onClick='$("#editInterface").fadeOut("fast");'>
		</div>
		<div class="ui segment mainUI popupInterface" >
			<div class="ui header">
				Edit Device Records
			</div>
			<p>Set Device Nickname</p>
			<div class="ui action fluid small input">
				<input class="deviceNickname" type="text" uuid="" placeholder="New Nickname" autocomplete="off">
				<button class="ui positive button" onclick="setNickName(this)">Update</button>
			</div>
			<div class="ui inverted positive segment nicnameSetConfirm" style="display:none;">
				<p><i class="checkmark icon"></i> Device Nickname Updated</p>
			</div>

			<div class="ui divider"></div>
			<br>
			<button class="ui primary button"  onClick='$("#editInterface").fadeOut("fast");'>Close</button>
			<br><br>

		</div>
	</div>

	<!-- Action can be done on this device -->
	<div id="actioninterface" class="ui active dimmer" style="display:none;">
		<div style="position:absolute;width:100%;height:100%;left:0px;top:0px;" onClick='$("#actioninterface").fadeOut("fast");'>
		</div>
		<div id="informationItnerface" class="ui segment mainUI popupInterface" style="text-align: left;">
		   <div class="ui header">
			  Device Actions
		   </div>
		   <br>
		   <div class="ui form" id="statusList">
				<h3><i class="ui loading spinner icon"></i> Loading</h3>
		   </div>
		   <div class="ui divider"></div>
		   <div class="ui horizontal form" id="actionForm">

			</div>
			<br>
			<button class="ui primary button"  onClick='$("#actioninterface").fadeOut("fast");'>Close</button>
			<br><br>
		</div>
	</div>

	<div id="loadingMask" class="ui active dimmer" style="display:none;">
	   <div class="ui text loader">Scanning in Progress</div>
	</div> 
	<script>
		var currentlyViewingDevices = "";
		var uselocal = false; //Use Local as command sender or use Host as command sender
		var username = $("#data_session_username").text().trim();
		//ao_module Float Window functions
		ao_module_setWindowTitle("IoT Hub");
		ao_module_setWindowSize(465,730,true);
		if (!ao_module_virtualDesktop){
			$("body").css("background-color","white");
		}

		//Initiate the page content
		loadDevList();

			
		function inputbox(message, placeholder = ""){
			var input = prompt(message, placeholder);
			if (input != null) {
			return input;
			}else{
			return false;
			}
		}


		function scanDevices(){
			$("#loadingMask").show();
			$.get("../../../system/iot/scan", function(data){
				loadDevList();
				$("#loadingMask").hide();
			});
		}


		function hideSideMenu(){
			$('.right.sidebar').sidebar('hide');
		}

		function showMore(object){
			var device = $(object).parent().parent();
			var duid = device.attr("uuid");
			var lastseen = device.attr("devip");
			var deviceData = device.attr("devicedata");
			deviceData = JSON.parse(decodeURIComponent(deviceData))
			console.log(deviceData);
			$("#duid").val(duid);
			$("#ipaddr").val(lastseen);
			$("#comport").val(deviceData.Port);
			$("#manufacturer").val(deviceData.Manufacturer);
			$("#version").val(deviceData.Version);
			currentlyViewingDevices = duid;
			$("#moreInfoInterface").fadeIn('fast');
		}

		function loadDevList(){
			$.get("../../../system/iot/list", function(data){
				$("#devList").html("");
				if (data.error !== undefined){
					alert(data.error);
				}else{
					data.forEach(device => {
						var deviceData = encodeURIComponent(JSON.stringify(device));
						$("#devList").append(`<div class="ui segment HDSDev" devicedata="${deviceData}" uuid="${device.DeviceUUID}" devIp="${device.IPAddr}" port="${device.Port}" location="local">
							<div class="ui grid">
								<div class="four wide column"><img class="ui tiny devIcon image" src="../../../system/iot/icon?devid=${device.DeviceUUID}"></div>
								<div class="twelve wide column">
									<div class="ui container">
										<div class="ui header">
											<span class="devHeader">${device.Name}</span>
											<div class="sub devProperty header">${device.Model}</div>
										</div>
									</div>
								</div>
							</div>
							<div class="controlBtn infoMount">
								<button class="ui icon button" title="Edit Device Nickname" onClick="edit(this);"><i class="edit icon"></i></button>
								<button class="ui icon button" title="Show More" onClick="showMore(this);"><i class="info circle icon"></i></button>
								<button class="ui primary icon button" title="Actions" onClick="action(this);"><i class="options icon"></i></button>
							</div>
						</div>`);
					});

					if (data.length == 0){
						//No device found
						$("#devList").html(`<div class="ui basic segment HDSDev">
							<div class="ui grid">
								<div class="four wide column"><img class="ui tiny devIcon image" src="img/system/not-found.svg"></div>
								<div class="twelve wide column">
									<div class="ui container">
										<div class="ui header">
											<span class="devHeader">No Device Found</span>
											<div class="sub devProperty header">Want to create your own IoT devices with ESP8266 & Arduino IDE? <br>Check out the <a href="https://github.com/tobychui/Home-Dynamic" target="_blank">HomeDynamic</a> System!</div>
										</div>
									</div>
								</div>
							</div>
						</div>`);
					}

					//Load the nickname of each device if it exists
					$(".HDSDev").each(function(){
						//Get iui nickname 
						var devUUID = $(this).attr("uuid");
						var targetDOMElement = $(this);
						$.ajax({
							url: "../../../system/iot/nickname",
							data: {opr: "get", uuid: devUUID},
							success: function(data){
								if (data.error == undefined){
									//No error. Render it to the header
									var currentHeader = $(targetDOMElement).find(".devHeader").text();
									var newHeader = data + " (" + currentHeader + ") ";
									$(targetDOMElement).find(".devHeader").text(newHeader);
								}
							}
						});
					})
					
				}
			});
		}

		function toggleSideMenu(){
			$("#sidemenu").sidebar('toggle');
		}

		function setNickName(input){
			var inputValue = $(input).parent().find(".deviceNickname").val();
			var devUUID = $(input).parent().find(".deviceNickname").attr("uuid");
			if (inputValue !== ""){
				//Set the new value
				$.ajax({
					url: "../../../system/iot/nickname",
					data: {opr: "set", uuid: devUUID, name: inputValue},
					success: function(data){
						if (data.error !== undefined){
							alert(data.error);
						}else{
							//OK!
							$("#editInterface").find(".nicnameSetConfirm").slideDown("fast").delay(3000).slideUp("fast");

							//Update the device list
							loadDevList();
						}
					}
				});
			}
		}

		function edit(object){
			//get the device UUID
			var devdata = $(object).parent().parent().attr("devicedata");
			devdata = JSON.parse(decodeURIComponent(devdata));
			var devUUID = devdata.DeviceUUID;
			$("#editInterface").find(".deviceNickname").attr("uuid",devUUID);

			//Get the device nickname from server side
			$.ajax({
				url: "../../../system/iot/nickname",
				data: {opr: "get", uuid: devUUID},
				success: function(data){
					if (data.error !== undefined){
						//Nickname not set yet. 
						$("#editInterface").find(".deviceNickname").val("");
					}else{
						$("#editInterface").find(".deviceNickname").val(data);
					}
				}
			})

			//Show the interface
			$("#editInterface").fadeIn('fast');



		}

		function executeEndpoint(object, targetValue=""){
			var deviceID = $(object).attr("devid");
			var epd = JSON.parse(decodeURIComponent($(object).attr("epd")));
			if (epd.Type == "integer" || epd.Type == "float"){
				//Check if it is in range
				if (epd.Max && targetValue > epd.Max ){
					//Snap to max value if over max
					targetValue = epd.Max;
				}

				if (epd.Min && targetValue < epd.Min){
					//Snap to min value if under min
					targetValue = epd.Min;
				}
			}else if (epd.Type == "string"){
				//Check if regex
				if (epd.Regex && targetValue.match(stringToRegex(epd.Regex)) == null){
					//Invalid string input. Reject operation
					alert("Input string does not match request regex structure: " + epd.Regex);
					return;
				}
			}

			//Request the backend to activate the endpoint
			console.log(deviceID, epd, targetValue);
			$.ajax({
				url: "../../../system/iot/execute",
				data: {devid: deviceID, eptname: epd.Name, payload: targetValue},
				success: function(data){
					if (data.error !== undefined){
						alert(data.error);
					}else{
						//OK. Reload status
						updateStatus(deviceID);
					}
				}
			})
		}

		const stringToRegex = str => {
			// Main regex
			const main = str.match(/\/(.+)\/.*/)[1]
			
			// Regex options
			const options = str.match(/\/.+\/(.*)/)[1]
			
			// Compiled regex
			return new RegExp(main, options)
		}

		function action(object){
			//Clear the action form
			$("#actionForm").html("");

			//Generate the list of endpoinui from the device data
			var device = $(object).parent().parent();
			var deviceData = device.attr("devicedata");
			deviceData = JSON.parse(decodeURIComponent(deviceData));

			var epts = deviceData.ControlEndpoints;
			if (epts == null || typeof(epts) == undefined || epts.length == 0 ){
				//This device has no control endpoints. Show status info only.
				updateStatus(deviceData.DeviceUUID);
			}else{
				epts.forEach(ept => {
					//Check which type of ept is this. Accept {string, integer, float, bool, none}
					var encodedEptData = encodeURIComponent(JSON.stringify(ept));
					var deviceID = deviceData.DeviceUUID;
					var name = ept.Name;
					if (ept.Type == "string"){
						$("#actionForm").append(`<div name="${ept.Name}" devid="${deviceID}" epd="${encodedEptData}" class="field">
							<label>${ept.Desc}</label>
							<div class="ui action input">
								<input type="text" placeholder="${name}">
								<button class="ui primary icon button" title="Send" onclick="executeEndpoint(this.parentNode.parentNode, this.parentNode.parentNode.getElementsByTagName('input')[0].value)"><i class="send icon"></i></button>
							</div>
						</div>`);
					}else if (ept.Type == "integer"){
						var min = "";
						var max = "";
						if (ept.Min != undefined){
							min = ept.Min;
						}

						if (ept.Max != undefined){
							max = ept.Max;
						}

						$("#actionForm").append(`<div name="${ept.Name}" devid="${deviceID}" epd="${encodedEptData}" class="field">
							<label>${ept.Desc}</label>
							<div class="ui action input">
								<input type="number" min="${min}" max="${max}" placeholder="${name}">
								<button class="ui primary icon button" title="Send" onclick="executeEndpoint(this.parentNode.parentNode, this.parentNode.parentNode.getElementsByTagName('input')[0].value)"><i class="send icon"></i></button>
							</div>
						</div>`);
					}else if (ept.Type == "float"){
						var min = "";
						var max = "";
						var step = "0.1";
						if (ept.Min != undefined){
							min = ept.Min;
						}

						if (ept.Max != undefined){
							max = ept.Max;
						}

						if (ept.Steps != undefined){
							step = ept.Steps;
						}

						$("#actionForm").append(`<div name="${ept.Name}" devid="${deviceID}" epd="${encodedEptData}" class="field">
							<label>${ept.Desc}</label>
							<div class="ui action input">
								<input type="number" min="${min}" max="${max}" step="${step}" placeholder="${name}">
								<button class="ui primary icon button" onclick="executeEndpoint(this.parentNode.parentNode, this.parentNode.parentNode.getElementsByTagName('input')[0].value)" title="Send"><i class="send icon"></i></button>
							</div>
						</div>`);
					}else if (ept.Type == "bool"){
						$("#actionForm").append(`<div name="${ept.Name}" devid="${deviceID}" epd="${encodedEptData}" class="field">
							<div class="ui toggle checkbox">
								<input type="checkbox" id="${encodeURIComponent(ept.Name)}" onchange="executeEndpoint(this.parentNode.parentNode, this.checked);">
								<label for="${encodeURIComponent(ept.Name)}">${ept.Name}</label>
						</div></div>`);
						
					}else if (ept.Type == "none"){
						//No action. (aka just a GET request endpoint)
						$("#actionForm").append(`<div devid="${deviceID}" epd="${encodedEptData}" class="field">
							<button class="ui info fluid button" title="${ept.Desc}" onclick="executeEndpoint(this.parentNode);">${name}</button>
						</div>`);
					}
				});

				updateStatus(deviceData.DeviceUUID);
			}

			console.log(deviceData);

			$("#actioninterface").fadeIn('fast');
		}

		function updateStatus(deviceUUID){
			//Get iui status
			$.ajax({
					url: "../../../system/iot/status",
					data: {devid: deviceUUID},
					success: function(data){
						//Look for fields that have the same name. If not, append it to status field
						if (data.error !== undefined){
							$("#statusList").html(`<h3>Connection Lost</h3><br><p>${data.error}</p>`);
						}else{
							//OK! Append it
							$("#statusList").html("");
							for (var key in data) {
								var found = false;
								$("#actionForm").find(".field").each(function(){
									var thisName = $(this).attr("name");
									if (thisName == key){
										//Set iui value
										var targetInput = $(this).find("input");
										if (targetInput.attr('type') == "checkbox"){
											//For handling checkbox
											if (data[key] == true){
												targetInput[0].checked = true;
											}else{
												targetInput[0].checked = false;
											}
										}else{
											//For handling other input fields
											$(this).find("input").val(data[key]);
										}
										
										found = true;
									}
								});

								if (found == false){
									//Append to status field
									$("#statusList").append(`<div class="ui header">
										${data[key]}
										<div class="sub header">${key}</div>
									</div>`);
								}
							}

						}
					}
				})
		}

		function updateIframeSize(){
			$("#controlUI").attr("width",$("#actionMainUI").width());
			$("#controlUI").attr("height",$("#actionMainUI").height());
			$("#controlUI").css("width",$("#actionMainUI").width());
			$("#controlUI").css("height",$("#actionMainUI").height());
		}

		$(window).on("resize",function(){
			updateIframeSize();
		});

		$(".thisYear").text(new Date().getFullYear());
	</script>
</body>
</html>